package com.xframe.domain.repository;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.xframe.domain.BaseModel;
import com.xframe.domain.role.IUserCredentials;
import com.xframe.domain.sys.*;
import com.xframe.domain.views.ModelConfigViewBuilderRunTime;
import com.xframe.event.bus.core.model.DataMessage;
import com.xframe.event.bus.core.msg.MessageSender;
import com.xframe.xdal.core.annotation.XAction;
import com.xframe.xdal.core.constant.ErrorCode;
import com.xframe.xdal.core.exception.DalFrameException;
import com.xframe.xdal.core.model.*;
import com.xframe.xdal.core.model.mapping.ITableInfo;
import com.xframe.xdal.core.model.mapping.TableInfoBuilder;
import com.xframe.xdal.core.tran.XTransaction;
import com.xframe.xdal.core.util.CollectionUtil;
import com.xframe.xdal.core.util.StringUtil;
import com.xframe.xdal.core.util.XReflect;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 模型基础存储
 * @ClassName: ModelBaseRepository
 * @Author: Lean.Liu
 * @CreateTime: 2023/4/10 9:15
 **/
public class  SysModelRepository extends SysBaseRepository {

    /**
     * 系统实体 创建 （无数据体）
     * @param domainType 类型 完整包名  class
     * @param desc  模型名称
     * @param userCredentials 创建人/修改人信息
     * @return
     * @throws DalFrameException
     */
    @XTransaction
    public Integer regBeanToModel(String domainType, String desc, IUserCredentials userCredentials){
        try {
            SysModel sysModel = SysModel.valueOf(domainType,desc,userCredentials);
            sysModel.setModelType("2");
            sysModel.check();
            //生成模型行为表数据（按钮数据）
            List<SysModelAct> sysModelActs = SysModelAct.getDefActionList(sysModel);
            Class<?> dataType = Class.forName(domainType);
            Annotation[] accessibleAnnotations = XReflect.getAccessibleAnnotations(dataType, XAction.class);
            Integer sortNum = 50 ;
            Map<String,String> map = new HashMap<>();
            for (Annotation accessibleAnnotation : accessibleAnnotations) {
                SysModelAct action = SysModelAct.createAction(sysModel, (XAction) accessibleAnnotation, sortNum);
                if(!map.containsKey(action.getModelId() + action.getCode())) {
                    sortNum = sortNum + 10;
                    sysModelActs.add(action);
                    map.put(action.getModelId() + action.getCode(),action.getModelId() + action.getCode());
                }
            }
            //新建网格视图,新增 编辑 视图，后端配置文件(default)
            List<SysModelConfig> sysModelViewConfig = ModelConfigViewBuilderRunTime.builderView(sysModel,userCredentials);
            List<SysModelConfig> sysModelConfigs = ModelConfigViewBuilderRunTime.builderConfig(sysModel,userCredentials);
            // 保存模型到
            createNewModel(sysModel,sysModelActs,sysModelViewConfig,sysModelConfigs);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return 0;
    }



    @XTransaction
    @Override
    public Integer createNew(IModel model, ITableInfo tableInfo) throws DalFrameException{
        SysModel sysModel = (SysModel)model;
        super.createNew(sysModel,tableInfo);
        batchCreate(SysModelAttr.class,sysModel.getModelAttrList(),100);
        if (!CollectionUtil.isEmpty(sysModel.getModelBelongList())){
            batchCreate(SysModelBelong.class,sysModel.getModelBelongList(),100);
        }
        if (!CollectionUtil.isEmpty(sysModel.getModelManyList())){
            batchCreate(SysModelMany.class,sysModel.getModelManyList(),100);
        }
        if (!CollectionUtil.isEmpty(sysModel.getAttrValProcList())){
            batchCreate(SysModelAttrValProc.class,sysModel.getAttrValProcList(),100);
        }
        return 1;
    }




    /**
     * 创建一个新的对象到数据库，存在修改，不存在新增
     * @param sysModel 被保存的对象
     *
     * @return
     */
    @XTransaction
    private Integer createNewModel(SysModel sysModel,
                                  List<SysModelAct> sysModelActs,
                                  List<SysModelConfig> sysModelViewConfig,
                                  List<SysModelConfig> sysModelConfigs){

        try{
            createNew(sysModel,TableInfoBuilder.BuildTableInfoByAnnotation(SysModel.class));

            if(CollUtil.isNotEmpty(sysModelActs)){
                batchCreate(SysModelAct.class,sysModelActs,100);
            }
            if(CollUtil.isNotEmpty(sysModelViewConfig)){
                batchSave(SysModelViewConfig.class,sysModelViewConfig,100);
            }
            if(CollUtil.isNotEmpty(sysModelConfigs)){
                batchSave(SysModelConfig.class,sysModelConfigs,100);
            }
        }catch (Exception exception){
            throw exception;
        }
        return 1;
    }




    /**
     * 删除一个对象
     * @param model 被保存的对象
     * @param tableInfo 数据表结构
     *
     * @return
     */
    @XTransaction
    @Override
    public Integer delete(IModel model, ITableInfo tableInfo) throws DalFrameException {
        if(model instanceof SysModel) {
            return deleteMode((SysModel)model);
        }else {
            return super.delete(model,tableInfo);
        }
    }

    /**
    * @description:删除模板
    * @param:[sysModel, userCredentials]
    * @return:java.lang.Integer
    * @author: ChaiXinQiang
    * @createDate: 16:29 2023/6/13
    **/
    @XTransaction
    private Integer deleteMode(SysModel sysModel){
        ITableInfo tableInfo = TableInfoBuilder.BuildTableInfoByAnnotation(SysModel.class);
        try {
            //物理删除模型数据
            DataAccessResult<Integer> result = defDataBaseAccess.deleteOperate(sysModel,tableInfo);
            if(!result.getSuccessFlag()){
                throw new DalFrameException(result.getCode(),result.getException().getMessage());
            }
            //物理删除字段表数据
            ConditionValueCollection conditionValueCollection = new ConditionValueCollection();
            conditionValueCollection.add(new ConditionValue("modelId",sysModel.getModelId()));
            deleteMany(TableInfoBuilder.BuildTableInfoByAnnotation(SysModelAttr.class),conditionValueCollection);
            //物理删除字段填充处理器数据
            deleteMany(TableInfoBuilder.BuildTableInfoByAnnotation(SysModelAttrValProc.class),conditionValueCollection);

            //删除子表
            deleteMany(TableInfoBuilder.BuildTableInfoByAnnotation(SysModelBelong.class),conditionValueCollection);
            //删除引用表
            deleteMany(TableInfoBuilder.BuildTableInfoByAnnotation(SysModelMany.class),conditionValueCollection);
            //删除模型行为数据
            deleteMany(TableInfoBuilder.BuildTableInfoByAnnotation(SysModelAct.class),conditionValueCollection);

            //删除视图和配置
            ConditionValueCollection whereCollection = new ConditionValueCollection();
            whereCollection.add(new ConditionValue("modelCode", sysModel.getModelCode()));
            deleteMany(TableInfoBuilder.BuildTableInfoByAnnotation(SysModelConfig.class), whereCollection);
            deleteMany(TableInfoBuilder.BuildTableInfoByAnnotation(SysModelViewConfig.class), whereCollection);
            return 1;
        }catch (Exception exception){
            throw new RuntimeException(exception);
        }
    }


}
